import axios from 'axios'
import router from '@/router/'
import qs from 'qs'
import { isEmpty, isFormData, filterObj } from '@/utils/common'
import { ElMessageBox, ElLoading } from 'element-plus'
let loadingInstance = null

let pending = [] // 声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let CancelToken = axios.CancelToken
let removePending = ever => {
    for (let p in pending) {
        if (pending[p].u === ever.url + '&' + ever.method) {
            // 当当前请求在数组中存在时执行函数体
            pending[p].f() // 执行取消操作
            pending.splice(p, 1) // 把这条记录从数组中移除
        }
    }
}

let baseURL = process.env.VUE_APP_BASE_API
const TIMEOUT_MILLISECONDS = 300000

function handleResponse (response, options) {
    if (options.isShowLoading) {
        loadingInstance.close()
    }
    if (response.status === 200) {
        const contentType = response.headers['content-type']
        if (contentType && contentType.indexOf('json') !== -1) {
            /* eslint no-eval: 0 */
            if (response.data.constructor === window.Blob) {
                let reader = new FileReader()
                reader.readAsText(response.data)
                reader.addEventListener('loadend', function () {
                    let res = JSON.parse(reader.result)
                    ElMessageBox.alert(res.message, '提示', {
                        confirmButtonText: '确定'
                    })
                })
            } else {
                const data = eval(response.data)
                const {
                    success,
                    message
                } = data
                if (!success && !options.noAlert) {
                    ElMessageBox.alert(message || '服务器异常', '提示')
                }
            }
        } else if (response.config && response.config.responseType === 'blob') {
            const blob = new Blob([response.data])
            const downloadElement = document.createElement('a')
            // const href = window.URL ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob)
            const href = window.URL.createObjectURL(blob)
            const dis = response.headers['content-disposition']
            const filenameKey = 'filename='
            const indexOf = dis.indexOf(filenameKey)
            const filename = indexOf ? decodeURI(dis.substring(indexOf + filenameKey.length)) : '未知文件名'
            downloadElement.href = href
            // downloadElement.download = decodeURIComponent(escape(filename))
            downloadElement.download = filename
            document.body.appendChild(downloadElement)
            downloadElement.click()
            // if (window.URL) {
            window.URL.revokeObjectURL(href)
            // } else {
            //  window.webkitURL.revokeObjectURL(href)
            // }
            document.body.removeChild(downloadElement)
        }
    } else if (response.status === 401) {
        router.push('/tms-web/exception/401')
    } else if (response.status > 400) {
        if (!options.noAlert) {
            ElMessageBox.alert(
                `异常编号：${response.status}，异常信息：${response.statusText}`,
                '服务器异常'
            )
        }
    }
}
const fetch = options => {
    let {
        method = 'get', data, url, headers, config, isCheckRepeat, needBaseUrl = true
    } = options
    const instance = axios.create({
        timeout: TIMEOUT_MILLISECONDS,
        // baseURL,
        baseURL: needBaseUrl ? baseURL : '',
        withCredentials: true,
        headers: {
            ...headers
        }
    })

    instance.interceptors.request.use(
        config => {
            // 判断是否需要显示满屏loading遮罩
            if (options.isShowLoading) {
                loadingInstance = ElLoading.service({
                    fullscreen: true
                })
            }
            removePending(config) // 在一个ajax发送前执行一下取消操作
            config.cancelToken = new CancelToken(c => {
                // 这里的ajax标识我是用请求地址&请求方式拼接的字符串，当然你可以选择其他的一些方式
                if (options.isCheckRepeat) {
                    pending.push({
                        u: config.url + '&' + config.method,
                        f: c
                    })
                }
            })
            return config
        },
        err => {
            return Promise.reject(err)
        }
    )

    instance.interceptors.response.use(
        response => {
            try {
                handleResponse(response, options)
                // ------------------------------------------------------------------------------------------
                removePending(options.config) // 在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
                // -------------------------------------------------------------------------------------------
            } catch (err) { }
            return response
        },
        err => {
            err.response && handleResponse(err.response, options)
            return Promise.reject(err)
        }
    )
    let filterData = isFormData ? data : filterObj(data)
    switch (method.toLowerCase()) {
        case 'get':
            return instance.get(
                `${url}${!isEmpty(data) ? `?${qs.stringify(data)}` : ''}`,
                config
            )
        case 'delete':
            return instance.delete(url, {
                data: filterData
            })
        case 'head':
            return instance.head(url, filterData)
        case 'post':
            return instance.post(url, filterData, config)
        case 'put':
            return instance.put(url, filterData, config)
        case 'patch':
            return instance.patch(url, filterData)
        default:
            return instance(options)
    }
}

export default function request (options) {
    return new Promise((resolve, reject) => {
        fetch(options)
            .then(response => {
                resolve(response.data)
            })
            .catch(error => {
                reject(error)
            })
    })
}
